package chartCraft.graphDesk;

import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.SwingConstants;
import javax.swing.border.AbstractBorder;



/**
 * MySwing: Advanced Swing Utilites
 * Copyright (C) 2005 Santhosh Kumar T
 * <p/>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p/>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * @author Santhosh Kumar T
 */
public class DefaultResizableBorder implements ResizableBorder{
	private static final long serialVersionUID = 1L;

	private int mDist = 6;

	private boolean mShowBorderFlag = false;

	int mLocations[] = {
			SwingConstants.NORTH,
			SwingConstants.SOUTH,
			SwingConstants.WEST,
			SwingConstants.EAST,
			SwingConstants.NORTH_WEST,
			SwingConstants.NORTH_EAST,
			SwingConstants.SOUTH_WEST,
			SwingConstants.SOUTH_EAST,
			0, // move
			-1, // no location
	};

	int mCursors[] = {
			Cursor.N_RESIZE_CURSOR,
			Cursor.S_RESIZE_CURSOR,
			Cursor.W_RESIZE_CURSOR,
			Cursor.E_RESIZE_CURSOR,
			Cursor.NW_RESIZE_CURSOR,
			Cursor.NE_RESIZE_CURSOR,
			Cursor.SW_RESIZE_CURSOR,
			Cursor.SE_RESIZE_CURSOR,
			Cursor.MOVE_CURSOR,
			Cursor.DEFAULT_CURSOR,
	};
	
	public int getThickness() {
		return mDist;
	}

	public DefaultResizableBorder(int dist){
		this.mDist = dist;
	}

	public Insets getBorderInsets(Component component){
		return new Insets(mDist, mDist, mDist, mDist);
	}

	/*
	 * (non-Javadoc)
	 * @see javax.swing.border.Border#isBorderOpaque()
	 * This tells the Swing that this object will not paint
	 * all of the bits contained within its rectangular bounds.
	 */
	public boolean isBorderOpaque(){
		return false;
	}

	public void paintBorder(Component component, Graphics g, int x, int y, int w, int h){
		if (mShowBorderFlag) {
			g.setColor(Color.black);
			g.drawRect(x+mDist/2, y+mDist/2, w-mDist, h-mDist);

			for(int i=0; i<mLocations.length-2; i++){
				Rectangle rect = getRectangle(x, y, w, h, mLocations[i]);
				g.setColor(Color.WHITE);
				g.fillRect(rect.x, rect.y, rect.width-1, rect.height-1);
				g.setColor(Color.BLACK);
				g.drawRect(rect.x, rect.y, rect.width-1, rect.height-1);
			}
		}
	}

	private Rectangle getRectangle(int x, int y, int w, int h, int location){
		switch(location){
		case SwingConstants.NORTH:
			return new Rectangle(x+w/2-mDist/2, y, mDist, mDist);
		case SwingConstants.SOUTH:
			return new Rectangle(x+w/2-mDist/2, y+h-mDist, mDist, mDist);
		case SwingConstants.WEST:
			return new Rectangle(x, y+h/2-mDist/2, mDist, mDist);
		case SwingConstants.EAST:
			return new Rectangle(x+w-mDist, y+h/2-mDist/2, mDist, mDist);
		case SwingConstants.NORTH_WEST:
			return new Rectangle(x, y, mDist, mDist);
		case SwingConstants.NORTH_EAST:
			return new Rectangle(x+w-mDist, y, mDist, mDist);
		case SwingConstants.SOUTH_WEST:
			return new Rectangle(x, y+h-mDist, mDist, mDist);
		case SwingConstants.SOUTH_EAST:
			return new Rectangle(x+w-mDist, y+h-mDist, mDist, mDist);
		}
		return null;
	}

	public int getResizeCursor(MouseEvent me){
		Component comp = me.getComponent();
		int w = comp.getWidth();
		int h = comp.getHeight();

		Rectangle bounds = new Rectangle(0, 0, w, h);
		if(!bounds.contains(me.getPoint())) {
			System.out.println("Default");
			return Cursor.DEFAULT_CURSOR;
		}

		Rectangle actualBounds = new Rectangle(mDist, mDist, w-2*mDist, h-2*mDist);
		if(actualBounds.contains(me.getPoint())) {
			return Cursor.MOVE_CURSOR;
		}

		for(int i=0; i<mLocations.length-2; i++){
			Rectangle rect = getRectangle(0, 0, w, h, mLocations[i]);
			if(rect.contains(me.getPoint())) {
				return mCursors[i];
			}
		}

		return Cursor.MOVE_CURSOR;
	}

	@Override
	public void showBorder(boolean flag) {
		mShowBorderFlag = flag;
	}
}
